package com.demo.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Aspect//这个注解的作用是:将一个类定义为一个切面类
@Component//这个注解的作用：把切面类加入到IOC容器中
@Slf4j
public class AspectDemo {

    /**
     * ..表示包及子包 该方法代表controller层的所有方法  TODO 路径需要根据自己项目定义
     */
    @Pointcut("execution(public * com.demo.controller..*.*(..))")
    public void controllerMethod() {
    }

    /**
     * 方法执行前
     *
     * @param joinPoint
     * @throws Exception
     */
    @Before("controllerMethod()")
    public void LogRequestInfo(JoinPoint joinPoint) throws Exception {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("========================请求内容======================");
        log.info("请求地址:" + request.getRequestURI().toString());
        log.info("请求方式" + request.getMethod());
        log.info("请求类方法" + joinPoint.getSignature());
        log.info("请求类方法参数" + Arrays.toString(joinPoint.getArgs()));
        log.info("========================请求内容======================");

    }


    /**
     * 方法执行后
     *
     * @param
     * @throws Exception
     */

    @AfterReturning(returning = "o", pointcut = "controllerMethod()")
    //这个注解的作用是:在切入点,return后执行,如果想对某些方法的返回参数进行处理,可以在这操作
    public void methodAfterReturing(Object o) {
        log.info("--------------返回内容----------------");
        log.info("Response内容:" + JSON.toJSONString(o));
        log.info("--------------返回内容----------------");
    }


    /**
     * 之后
     * @param joinPoint
     */
    @After("controllerMethod()")
    public void logEnd(JoinPoint joinPoint) {
        System.out.println(joinPoint.getSignature().getName() + "结束...");
    }


    /**
     * 异常信息
     *
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value = "controllerMethod()", throwing = "e")
    public void logException(JoinPoint joinPoint, Exception e) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        log.info("请求地址:" + request.getRequestURI());
        log.info("请求类方法" + joinPoint.getSignature());
        log.info("异常，异常信息:" + JSONObject.toJSONString(e.getMessage()));
    }

}
